package com.kuang.volatiledemo;

import java.util.concurrent.TimeUnit;

/**
 * volatile :
 *      1.保证可见性
 *      2.不保证原子性
 *      3.禁止指令重排
 *
 * 验证1：保证可见性
 *      参考文章：
 *          C语言丨深入理解volatile关键字 - 沐歌爱编程的文章 - 知乎 https://zhuanlan.zhihu.com/p/343688629
 *      多线程操作共享变量时，可见性问题：
 *          线程A正在用flag = true，进行工作，还没有写入主内存时，线程B修改flag = false，并写入了内容中，
 *          这时候就会有线程A工作内存中的flag与主存中值不一致。
 *      处理思路：
 *          需要线程A知道主内存中的值发生了变化
 *      解决办法：
 *          对共享变量用 volatile进行修饰，说明这个变量是“易变的”，
 *          提醒编译器，编译后的程序每次需要对这个变量操作的时候，不要做编译优化（不要读取工作内存的值），
 *          直接从变量内存地址中读取数据，从而解决对主内存共享变量变化时对A线程不可见现象。
 */
public class Demo1 {
    // 共享变量
    // 当没有volatile修饰时，打印出1，还继续陷入死循环，程序不中断
    // 当有volatile修饰时，打印出1，立即中断
    //private  static int num = 0;
    private volatile static int num = 0;
    public static void main(String[] args) {
        // 线程1  当num=0时，死循环
        new Thread(()->{
            while (num == 0){
            }
        },"线程1").start();

        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // main线程  修改num=1
        num = 1;
        System.out.println(num);

    }
}
